﻿
Imports System.Threading
Imports osi.root.lock.slimlock
Imports osi.root.delegates

Public Class atom(Of T, LOCK_T As {islimlock, Structure})
    Implements iatom(Of T)
    Protected p As T = Nothing
    Private l As LOCK_T

    Public Sub New()
    End Sub

    Public Sub New(ByVal i As T)
        [set](i)
    End Sub

    Protected Overridable Function atomic_read(ByRef p As T) As T
        Return atomic.read(p)
    End Function

    Public Function [get]() As T Implements iatom(Of T).get
        Return atomic_read(p)
    End Function

    Protected Overridable Sub atomic_write(ByRef p As T, ByVal i As T)
        atomic.eva(p, i)
    End Sub

    Public Sub [set](ByVal i As T) Implements iatom(Of T).set
        atomic_write(p, i)
    End Sub

    Public Sub modify(ByVal d As void(Of T)) Implements iatom(Of T).modify
        If Not d Is Nothing Then
            l.k_locked(Sub() d(p))
        End If
    End Sub

    Public Overridable Function compare_exchange(ByVal value As T,
                                                 ByVal comparand As T) As T Implements iatom(Of T).compare_exchange
        Return Interlocked.CompareExchange(p, value, comparand)
    End Function

    Public Shared Operator +(ByVal this As atom(Of T, LOCK_T)) As T
        Return If(this Is Nothing, Nothing, this.get())
    End Operator
End Class

Public Class atom(Of T)
    Inherits atom(Of T, spinlock)

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal i As T)
        MyBase.New(i)
    End Sub
End Class
